package ru.sgu.acm.judge.misc;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;
import org.cyberneko.html.parsers.DOMParser;

import java.io.IOException;
import java.io.StringReader;

/**
 * This class contains current session.
 * It can create new session and return current.
 * This class contains methods for work with currend session and
 * some helper methods.
 *
 * @author Vitaly Goldshteyn (VitalyGoldstein@gmail.com)
 */
public class Browser {
    private static HttpClient session;

    /**
     * @return current session.
     */
    public static HttpClient getCurrentSession() {
        if (session == null) {
             session = newSession();
        }
        return session;
    }

    /**
     * Create new session and return it. All calls of getCurrentSession
     * will return this new session.
     * @return new session.
     */
    public static HttpClient newSession() {
        session = new HttpClient();
        return session;
    }

    /**
     * @param statusCode http method result code.
     * @return is statusCode of httpmethod is error code.
     */
    public static boolean isHttpMethodErrorStatusCode(int statusCode) {
        return statusCode / 100 == 4;
    }

    /**
     * Download web page using current session and return DOM parsed document.
     * @param url of web page
     * @return DOM parsed document
     * @throws IOException if unable to download web page.
     * @throws SAXException if unable to parse web page.
     */
    public static Node getHtmlDocumentFromCurrentSession(String url) throws IOException, SAXException {
        GetMethod getMethod = new GetMethod(url);
        getCurrentSession().executeMethod(getMethod);
        if (isHttpMethodErrorStatusCode(getMethod.getStatusCode())) {
            throw new IOException("Method return error status code during checking status: "
                    + getMethod.getStatusText());
        }
        String inp = getMethod.getResponseBodyAsString();
        inp = inp.replaceAll("xmlns[\\s]*=[\\s]*[^\\s]*", " ");
        inp = inp.replaceAll("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">", " ");
        DOMParser parser = new DOMParser();
        parser.parse(new InputSource(new StringReader(inp)));
        return parser.getDocument();
    }


}
